package model

import (
	"context"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"github.com/gogf/gf/v2/util/gconv"
	v1 "goAdminV1/api/role/v1"
	"goAdminV1/internal/dao"
	"goAdminV1/internal/model/entity"
	"strconv"
)

// RoleResult 定义角色查询结果的结构体
type RoleResult struct {
	Roles []v1.RoleInfo `json:"roles"`
	Total int           `json:"total"`
}

// GetRoles 用于查询角色列表
func GetRoles(ctx context.Context, limit, page int, roleName string) (*RoleResult, error) {
	var roles []v1.RoleInfo
	offset := (page - 1) * limit

	// 构建基础查询
	query := dao.CaRoles.Ctx(ctx)

	// 根据 roleName 参数添加查询条件
	if roleName != "" {
		query = query.Where("role_name LIKE?", "%"+roleName+"%")
	}

	// 复制查询用于统计总数
	countQuery := *query
	var total int
	_, err := countQuery.Count(&total)
	if err != nil {
		return nil, err
	}

	// 应用分页并查询角色列表
	query = query.Limit(limit).Offset(offset)
	err = query.Scan(&roles)
	if err != nil {
		return nil, err
	}

	// 遍历每个角色，查询其关联的权限
	for i := range roles {
		var permissions []v1.RoleListPermission
		rows, err := dao.CaRoleHasPermissions.Ctx(ctx).
			Where("role_id", roles[i].Id).
			Fields("permission_id").
			All()
		if err != nil {
			return nil, gerror.Wrap(err, "查询角色关联的权限列表失败")
		}

		for _, row := range rows {
			permissionId := gconv.Int(row["permission_id"])
			permissions = append(permissions, v1.RoleListPermission{
				ID: permissionId,
			})
		}
		// 将查询到的权限添加到对应的角色结构体中
		roles[i].Permissions = permissions
	}

	result := &RoleResult{
		Roles: roles,
		Total: total,
	}
	return result, nil
}

// ExistsByIdentify 检查角色标识是否已存在
func ExistsByIdentify(ctx context.Context, identify string) (bool, error) {
	count, err := dao.CaRoles.Ctx(ctx).Where("identify", identify).Count()
	if err != nil {
		return false, err
	}
	return count > 0, nil
}

// CreateRole 创建角色
func CreateRole(ctx context.Context, role entity.CaRoles) (int, error) {
	result, err := dao.CaRoles.Ctx(ctx).Data(role).Insert()
	if err != nil {
		return 0, err
	}
	roleId, err := result.LastInsertId()
	return int(roleId), err
}

// InsertRolePermissions 关联角色权限
func InsertRolePermissions(ctx context.Context, roleId int, permissions []string) error {
	if len(permissions) == 0 {
		return nil
	}
	// 批量插入数据
	batchData := make([]map[string]interface{}, len(permissions))
	for i, permissionStr := range permissions {
		permissionId, err := strconv.Atoi(permissionStr)
		if err != nil {
			g.Log().Errorf(ctx, "将权限字符串 %s 转换为整数时出错: %v", permissionStr, err)
			return gerror.Wrapf(err, "将权限 %s 转换为整数失败", permissionStr)
		}
		batchData[i] = map[string]interface{}{
			"role_id":       roleId,
			"permission_id": permissionId,
		}
	}
	_, err := g.DB().Model("role_has_permissions").Ctx(ctx).Data(batchData).Insert()
	if err != nil {
		return gerror.New("角色权限关联失败")
	}
	return nil
}

// GetRoleById 根据角色 Id 获取角色信息
func GetRoleById(ctx context.Context, id int) (*entity.CaRoles, error) {
	var role entity.CaRoles
	err := dao.CaRoles.Ctx(ctx).Where("id", id).Scan(&role)
	if err != nil {
		return nil, err
	}
	return &role, nil
}

// UpdateRole 更新角色信息
func UpdateRole(ctx context.Context, id int, data map[string]interface{}) error {
	_, err := dao.CaRoles.Ctx(ctx).Where("id", id).Data(data).Update()
	return err
}

// DeleteRolePermissions 删除角色权限关联
func DeleteRolePermissions(ctx context.Context, roleId int) error {
	_, err := dao.CaRoleHasPermissions.Ctx(ctx).Where("role_id", roleId).Delete()
	return err
}

// DeleteRoleById 根据角色 Id 删除角色
func DeleteRoleById(ctx context.Context, id int) error {
	_, err := dao.CaRoles.Ctx(ctx).Where("id", id).Delete()
	return err
}
